package de.clapp.client.menue;

import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.table.AbstractTableModel;

import de.clapp.backend.database.Conn;
import de.clapp.backend.database.Queries;
import de.clapp.data.Artikel;

@SuppressWarnings("serial")
public class MenueTableModel extends AbstractTableModel
{
    private ArrayList<Artikel> menue;
    private ArrayList<Artikel> loeschen;
    private ArrayList<Artikel> aktuell;
    private final String[] columnNames = {"Artikel", "Preis", "Kategorie"};
    private MenueCardPanel view;
    
    public MenueTableModel(String[] colNames, int rowNum, MenueCardPanel view)
    {
        menue = new ArrayList<Artikel>();
        loeschen = new ArrayList<Artikel>();
        
        this.view = view;
    }
    
    @Override
    public int getColumnCount()
    {
        return 3;
    }

    @Override
    public int getRowCount()
    {
        return this.menue.size();
    }
    
    @Override
    public String getColumnName(int column)
    {
        return columnNames[column];
    }
    
    @Override
    public Object getValueAt(int rowIndex, int columnIndex)
    {
        switch(columnIndex){
            case 0:
                return this.menue.get(rowIndex).getName();
            case 1:
                if(this.menue.get(rowIndex).getEinzelPreis() == 0)
                {
                    return "";
                }
                else
                {
                    return this.menue.get(rowIndex).getEinzelPreis();
                }
            case 2:
                return this.menue.get(rowIndex).getKategorie();
            default:
                return null;
        }
    }
    
    public boolean isCellEditable(int row, int col)
    {
        return true;
    }
    
    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex)
    {
        switch(columnIndex){
            case 0:
                this.menue.get(rowIndex).setName((String) value);
                break;
            case 1:
                this.checkInput(rowIndex, columnIndex, value.toString());
                this.menue.get(rowIndex).setEinzelPreis(Double.parseDouble((String)value));
                break;
            case 2:
                this.menue.get(rowIndex).setKategorie((String) value);
                break;
            default:
                break;
        }
        
        fireTableCellUpdated(rowIndex, columnIndex);
    }
    
    public void addRow()
    {
        this.menue.add(new Artikel());
        this.fireTableDataChanged();
    }
    
    public void removeRow(int index)
    {
        this.loeschen.add(menue.get(index));
        this.menue.remove(index);     
        this.fireTableDataChanged();
    }
    
    
    public void checkInput(final int rowIndex, int columnIndex, final String text)
    {
        if(columnIndex == 1)
        {
            //final String text = value.toString();
            // Pattern erlaubt: 1000 / 1000, / 1000,0 / 1000,00
            Pattern p = Pattern.compile("[0-9]*.?+[0-9]{0,2}+");
            Matcher m = p.matcher(text);
    
            if (!m.matches())
            {
                EventQueue.invokeLater(new Runnable()
                {
    
                    @Override
                    public void run()
                    {
                        //gesamtTF.setText(gesamtTF.getText().substring(0, gesamtTF.getText().length() - 1));
                        //text = text.substring(0, text.length()-1);
                        menue.get(rowIndex).setEinzelPreis(Double.parseDouble(text.substring(0, text.length() - 1)));
                    }
    
                });
               // return text = text.substring(0, text.length()-1);
                
            }
            else
            {
                //return text;
            }
        }
    }
    
    public void speichern()
    {
        view.speichern();
        this.speichernDB();          
    }
    
    public void speichernDB()
    {
        Connection con = Conn.getInstance().clientCon;
        
        //int id;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try
        {
            for (Artikel a : menue)
            {
                if(a.getName() != null  && a.getEinzelPreis() != 0)
                {
                    //Artikel noch nicht vorhanden -> Insert in DB
                    if(a.getIdArtikel() == -1)
                    {
                        pstmt = con.prepareStatement(Queries.INSERT_ARTIKEL);
                        pstmt.setString(1, a.getName());
                        pstmt.setDouble(2, a.getEinzelPreis());
                        pstmt.setString(3, a.getKategorie());
                    }
                    //Artikel bereits vorhanden -> Update in DB
                    else
                    {
                        pstmt = con.prepareStatement(Queries.UPDATE_ARTIKEL);
                        pstmt.setDouble(1, a.getEinzelPreis());
                        pstmt.setString(2, a.getKategorie());
                        pstmt.setInt(3, a.getIdArtikel());
                    }
                    pstmt.execute();
                }
            }
            for (Artikel a : loeschen)
            {
                pstmt = con.prepareStatement(Queries.DELETE_ARTIKEL);
                pstmt.setInt(1, a.getIdArtikel());
                pstmt.execute();
            }
            con.commit();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (pstmt != null)
            {
                try
                {
                    pstmt.close();
                }
                catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
            if (rs != null)
            {
                try
                {
                    rs.close();
                }
                catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
        }
        aktuell = new ArrayList<Artikel>(menue);
    }
    
    public void fillTable()
    {
        Connection con = Conn.getInstance().clientCon;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try
        {
            pstmt = con.prepareStatement(Queries.GET_ARTIKEL);
            rs = pstmt.executeQuery();
            
            //Speichere Artikel aus DB in Objekten
            while (rs.next())
            {
                Artikel a = new Artikel();
                a.setIdArtikel(rs.getInt("ID_ARTIKEL"));
                a.setName(rs.getString("NAME"));
                a.setEinzelPreis(rs.getDouble("EINZELPREIS"));
                a.setKategorie(rs.getString("KATEGORIE"));
                menue.add(a);
            }
            pstmt.close();
            rs.close();
            
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (pstmt != null)
            {
                try
                {
                    pstmt.close();
                }
                catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
            if (rs != null)
            {
                try
                {
                    rs.close();
                }
                catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
        }
        aktuell = new ArrayList<Artikel>(this.menue);
        fireTableDataChanged();
    }

    public void cancel()
    {
        menue = new ArrayList<Artikel>(this.aktuell);
        loeschen = new ArrayList<Artikel>();
        fireTableDataChanged();
    }
}
